package com.lanou.websocket;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
/**
 * Created by dllo on 18/3/26.
 */

/**
 * @ServerEndpoint 注解是一个类层次的注解，它的功能主要是将目前的类定义成一个websocket服务器端,
 * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
 */
@ServerEndpoint("/websocket/{username}")
public class Websocket {
    private static Map<String, Session> sessionMap = new HashMap<String, Session>();
    //静态变量，用来记录当前在线连接数。
    private static int onlineCount = 0;
    //接收者名字
    private String receiver;

    /**
     * @param username 用户认证名
     * @param session  session为与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(@PathParam("username") String username, Session session) {
//		this.session=session;
        sessionMap.put(username, session); //加入set中
        addOnlineCount();              //在线数加1
        System.out.println("有新连接" + username + "加入！当前在线人数为" + getOnlineCount());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        sessionMap.remove(session);
        subOnlineCount();           //在线数减1
        System.out.println("有一连接关闭！当前在线人数为" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(@PathParam("username") String username, String message) {
        receiver = message.substring(message.indexOf(":") + 1, message.length());
        message = message.substring(0, message.indexOf(":"));
        try {
            if (!receiver.equals("")) {
                sendMessageToOne(username, message, receiver);
            } else {
                sendMessageToAll(username, message);
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("hahah");
        }
        System.out.println("来自客户端" + username + "的消息:" + message);
    }

    /**
     * 发生错误时调用
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }

    /**
     * 发送给特定人的方法
     *
     * @param username 认证名
     * @param message  发送的信息
     * @param receiver 接收者
     * @throws IOException
     */
    public void sendMessageToOne(String username, String message, String receiver) throws IOException {
        if (!username.equals(receiver)) {
            if (sessionMap.containsKey(receiver)) {
                sessionMap.get(username).getAsyncRemote().sendText(username + ":" + message);
                sessionMap.get(receiver).getAsyncRemote().sendText("<span style='color:#b910cb'>来自<a onclick='getname(" + username + ")'>" + username + "</a>的消息:" + message + "</span>");
            } else {
                sessionMap.get(username).getAsyncRemote().sendText("<span style='color:red'>对方用户不存在或已下线</span>");
//                throw new NullPointerException("[" + username + "]Connection does not exist");
            }
        }else {
            sessionMap.get(username).getAsyncRemote().sendText("<span style='color:red'>谁这么傻,给自己发消息</span>");
        }

    }

    /**
     * 发送给所有人的方法
     *
     * @param username 认证名
     * @param message  发送信息
     * @throws IOException
     */
    public void sendMessageToAll(String username, String message) throws IOException {
        for (Session item : sessionMap.values()) {
            if (!item.equals(sessionMap.get(username))){
            item.getAsyncRemote().sendText("<span style='color:#b910cb'>来自<a onclick='getname(" + username + ")'>" + username + "</a>的消息:" + message + "</span>");
            }else {
                item.getAsyncRemote().sendText("<span><a onclick='getname(" + username + ")'>" + username + "</a>:" + message + "</span>");
            }
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        Websocket.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        Websocket.onlineCount--;
    }
}
